using System;
using System.Reflection;
using System.Diagnostics;
using System.Web;
using System.IO;
using System.Xml;
using System.Configuration;
using System.Text;
using System.Data;
using System.Windows.Forms;

namespace WP.Commons
{
	/// <summary>
	/// Summary description for ExceptionManager.
	/// </summary>
	public class ExceptionManager
	{
		public ExceptionManager()
		{
			//
			// TODO: Add constructor logic here
			//
		}

		#region GetExceptionInfo:Get exception file,class and method  infomation
		public static ExceptionFileInfo GetExceptionInfo(Exception e)
		{
			int framecount=0;
			ExceptionFileInfo info=new ExceptionFileInfo();
			StackTrace st=null;
			StackFrame sf=null;

			while(e.InnerException!=null)
			{
				e = e.InnerException;
			}

            st=new StackTrace(true) ;
            for (int i=0;i<st.FrameCount;i++)
            {
                sf=st.GetFrame(i);
                if(sf.GetFileName()!=""&&sf.GetFileName()!=null)	
                {
                    continue;
                }
                else
                {
                    framecount = i;
                    break;
                }
    	
            }

            if (framecount - 1 > 0)
                sf = st.GetFrame(framecount - 1);
            else
                sf = st.GetFrame(0);

			try
			{
				MemberInfo mi=sf.GetMethod();
			
				info.Method=mi.DeclaringType.Namespace+"."+mi.DeclaringType.Name+"."+mi.Name;

                #region complex condiction

                string strStackTrace = e.StackTrace;
                string strStackFrame = "";
                string strUserFuncException = "";
                string strSystemFuncException = "";
                int iStackFrameCount = 0;
                int iOneFrameEnd = 0;

                strStackTrace += "\r\n";
                for (int i = 0; i < strStackTrace.Length; i++)
                {
                    if (strStackTrace.IndexOf("   at ", i) > -1)
                    {
                        iStackFrameCount += 1;
                        i = strStackTrace.IndexOf("   at ", i) + 5;
                        iOneFrameEnd = strStackTrace.IndexOf("\r\n", i);
                        strStackFrame = strStackTrace.Substring(i, iOneFrameEnd - i);

                        if (strStackFrame.IndexOf(" in ") > -1)
                        {
                            strStackFrame = strStackFrame.Replace(" in ", "#");
                            strUserFuncException += strStackFrame + "$";
                        }
                        else
                        {
                            strSystemFuncException += strStackFrame + "$";
                        }

                    }
                }
                
                if (iStackFrameCount >1)
                {
                    //Construct dataTable of the Exception.
                    DataTable dtExpection = new DataTable();
                    dtExpection.TableName = "ExceptionInfo";
                    dtExpection.Columns.Add("MethodName");
                    dtExpection.Columns.Add("FileName");
                    dtExpection.Columns.Add("FileLineNumber");
                    dtExpection.Columns.Add("IsUser");

                    if (strUserFuncException.Length > 0)
                    {
                        strUserFuncException = strUserFuncException.Substring(0, strUserFuncException.Length - 1);

                        string[] strUserFuncExArray = strUserFuncException.Trim().Split('$');

                        for (int i = 0; i < strUserFuncExArray.Length; i++)
                        {
                            DataRow drExpection = dtExpection.NewRow();
                            string[] strArrayUser = strUserFuncExArray[i].Trim().Split('#');
                            drExpection["MethodName"] = strArrayUser[0];
                            drExpection["IsUser"] = "Yes";

                            if (strArrayUser[1].IndexOf(":line") > -1)
                            {
                                drExpection["FileName"] = strArrayUser[1].Substring(0, strArrayUser[1].IndexOf(":line"));
                                drExpection["FileLineNumber"] = strArrayUser[1].Substring(strArrayUser[1].IndexOf(":line") + 6);
                            }
                            else
                            {
                                drExpection["FileName"] = "";
                                drExpection["FileLineNumber"] = "";
                            }

                            dtExpection.Rows.Add(drExpection);
                        }
                    }

                    if (strSystemFuncException.Length > 0)
                    {
                        strSystemFuncException = strSystemFuncException.Substring(0, strSystemFuncException.Length - 1);

                        string[] strSystemFuncExArray = strSystemFuncException.Trim().Split('$');

                        for (int i = 0; i < strSystemFuncExArray.Length; i++)
                        {
                            DataRow drExpection = dtExpection.NewRow();
                            string[] strArraySystem = strSystemFuncExArray[i].Trim().Split('#');
                            drExpection["MethodName"] = strArraySystem[0];
                            drExpection["IsUser"] = "No";

                            drExpection["FileName"] = "";
                            drExpection["FileLineNumber"] = "";

                            dtExpection.Rows.Add(drExpection);
                        }
                    }

                    info.StackInfo = dtExpection;
                }
                #endregion
            }
			catch
			{
				info.Method="N/A - Reflection Permission required";
			}

			if( sf.GetFileName() != "")
			{

				info.FileName = sf.GetFileName();
				info.FileColumnNumber = sf.GetFileColumnNumber().ToString();
				info.FileLineNumber = sf.GetFileLineNumber().ToString();
				return info;
			}
			else
			{
				return null;

			}
		}
		#endregion
		
		#region Process Exection
		public static void ProcessException(Exception exception, ExceptionType extype)
		{
			//-----------------------------------------------
			//Nead to open form or to write error message to log file or database or email
			//------------------------------------------------

            BaseException baseException = new BaseException(exception.Message, exception);

            if (baseException != null)
            {
                if (System.Diagnostics.Debugger.IsAttached)
                {
                    OpenExceptionForm(baseException);
                }
                else
                {
                    MsgBoxEx.Show(exception.Message,SysVar.WarnTitle , MessageBoxButtons.OK , MessageBoxIcon.Warning );
                }
            }

		}

        public static void ProcessException(Exception exception)
        {
            ProcessException(exception, ExceptionType.System);
        }
		#endregion

        #region OpenExceptionForm:
        public static void OpenExceptionForm(BaseException baseException)
		{

            frmExceptionMsg FrmEx = new frmExceptionMsg();
			FrmEx.ExceptionMessage = baseException.Message;
            FrmEx.ModuleName = baseException.ModuleName;
            FrmEx.MethodName = baseException.MethodName;
            FrmEx.FileName = baseException.FileName;
            FrmEx.FileLineNumber = baseException.FileLineNumber;
            FrmEx.FileColumnNumber = baseException.FileColumnNumber;
            FrmEx.StackInfo = baseException.StackInfo;
            FrmEx.ShowDialog();
		}
		#endregion 

		#region WriteExceptionToTxt:
		public static void WriteExceptionToTxt(BaseException baseException)
		{
			string strPath ="";
			string exFilePath="";
			string strContent="";

			strContent = baseException.Message;
			strContent += "  "+baseException.DataTime;
            strContent += "  "+baseException.FileName;
			strContent += "  "+baseException.CodeSignNo;
			strContent += "  "+baseException.AbsolutePath;
			strContent += "  "+baseException.AbsoluteURL;
			strContent += "  "+baseException.ModuleName;
			strContent += "  "+baseException.MethodName;
			strContent += "  "+baseException.FileLineNumber;
			strContent += "  "+baseException.FileColumnNumber;
           
			strPath="Exception"+DateTime.Now.Year.ToString()+DateTime.Now.Month.ToString().PadLeft(2,'0')+DateTime.Now.Day.ToString().PadLeft(2,'0')+".txt";
			exFilePath=SysVar.MessageLogFilePath;

			if (exFilePath!="")
			{  
				if(exFilePath.Substring(exFilePath.Length-1,1)=="\\")
				{
					strPath=exFilePath+strPath;
				}
				else
				{
					strPath=exFilePath+ "\\"+strPath;
				}
			}

			if (!File.Exists(strPath)) 
			{
				using (StreamWriter sw = File.CreateText(strPath))
				{
					sw.WriteLine("Exception: ");			
				}
			}
         
			using (StreamWriter sw = File.AppendText(strPath)) 
			{
				sw.WriteLine(strContent + "\n");
			}
			
			
		}
		#endregion 

		#region WriteExceptionToXML: Write exception information to XML file
		private static void WriteExceptionToXML(BaseException baseException)
		{

			string strPath ="";
			string exFilePath="";

           
			strPath="Exception"+DateTime.Now.Year.ToString()+DateTime.Now.Month.ToString().PadLeft(2,'0')+DateTime.Now.Day.ToString().PadLeft(2,'0')+".xml";
			exFilePath=SysVar.MessageLogFilePath;

			if(exFilePath != null)
			{
				if (exFilePath!="")
				{  
					if(exFilePath.Substring(exFilePath.Length-1,1)=="\\")
					{
						strPath=exFilePath+strPath;
					}
					else
					{
						strPath=exFilePath+ "\\"+strPath;
					}
				}
			}

			DataSet ds = new DataSet();
			DataTable dt = new DataTable();
			ds.Tables.Add(dt);
			DataColumn dc0 = new DataColumn("Message",typeof(System.String));
			DataColumn dc1 = new DataColumn("DateTime",typeof(System.String));
			DataColumn dc2 = new DataColumn("FileName",typeof(System.String));
			DataColumn dc3 = new DataColumn("CodeSignNo",typeof(System.String));
			DataColumn dc4 = new DataColumn("AbsolutePath",typeof(System.String));
			DataColumn dc5 = new DataColumn("AbsoluteURL",typeof(System.String));
			DataColumn dc6 = new DataColumn("ModuleName",typeof(System.String));
			DataColumn dc7 = new DataColumn("MothedName",typeof(System.String));
			DataColumn dc8 = new DataColumn("FileLineNumber",typeof(System.String));
			DataColumn dc9 = new DataColumn("FileColumnNumber",typeof(System.String));
			ds.Tables[0].Columns.Add(dc0);
			ds.Tables[0].Columns.Add(dc1);
			ds.Tables[0].Columns.Add(dc2);
			ds.Tables[0].Columns.Add(dc3);
			ds.Tables[0].Columns.Add(dc4);
			ds.Tables[0].Columns.Add(dc5);
			ds.Tables[0].Columns.Add(dc6);
			ds.Tables[0].Columns.Add(dc7);
			ds.Tables[0].Columns.Add(dc8);
			ds.Tables[0].Columns.Add(dc9);



//			XmlTextWriter writer = new 
//				XmlTextWriter(strPath, Encoding.UTF8);
//			writer.Formatting = Formatting.Indented;
//			writer.Indentation=4;

			if(File.Exists(strPath))
			{
				ds.ReadXml(strPath);
		
			}

			DataRow dr = ds.Tables[0].NewRow();
			dr["Message"] = baseException.Message;
			dr["DateTime"] = baseException.DataTime;
			dr["FileName"] = baseException.FileName;
			dr["CodeSignNo"] = baseException.CodeSignNo;
			dr["AbsolutePath"] = baseException.AbsolutePath;
			dr["AbsoluteURL"] = baseException.AbsoluteURL;
			dr["ModuleName"] = baseException.ModuleName;
			dr["MothedName"] = baseException.MethodName;
			dr["FileLineNumber"] = baseException.FileLineNumber;
			dr["FileColumnNumber"] = baseException.FileColumnNumber;
			ds.Tables[0].Rows.Add(dr);
			
			ds.DataSetName = "Exception";
			ds.Tables[0].TableName = "Exc"+ DateTime.Now.Year.ToString()+DateTime.Now.Month.ToString().PadLeft(2,'0')+DateTime.Now.Day.ToString().PadLeft(2,'0');
			ds.WriteXml(strPath);
			
		}
		#endregion 

		#region SendExceptionByEMail:Send exception information to woodpro by email
//		private static void SendExceptionByEMail(BaseException baseException)
//		{
//			string mailFrom;
//			string mailTo;
//			string subject;
//			string messageContent;
//
//			mailFrom = ConfigurationSettings.AppSettings["MailFrom"];
//			mailTo = ConfigurationSettings.AppSettings["MailTo"];
//			subject = ConfigurationSettings.AppSettings["Subject"];
//			messageContent = "Exception :"+"\n";
//            messageContent += " " + baseException.Message;
//			messageContent += " " + baseException.DataTime;
//			messageContent += " " + baseException.FileName;
//			messageContent += " " + baseException.CodeSignNo;
//			messageContent += " " + baseException.AbsolutePath;
//			messageContent += " " + baseException.AbsoluteURL;
//			messageContent += " " + baseException.ModuleName;
//			messageContent += " " + baseException.MothedName;
//			messageContent += " " + baseException.FileLineNumber;
//			messageContent += " " + baseException.FileColumnNumber;
//			messageContent += "\n";
//            System.Web.Mail.SmtpMail.SmtpServer = "smtp.tom.com";
//
//
//			System.Web.Mail.SmtpMail.Send(mailFrom,mailTo,subject,messageContent);
//		}
		#endregion 

		#region IsWriteExceptionToDatabase:Write exciption inormation to database
		private static void IsWriteExceptionToDatabase(BaseException baseException)
		{
			
		}
		#endregion 
	}
}
